#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <cstring>

#define PATH "."
#define PROJIN 0x666

const int default_fd = -1;
const int default_size = 1024;

#define GET_MSGQUEUE (IPC_CREAT)
#define GREAT_MSGQUEUE (IPC_CREAT | IPC_EXCL | 0666)

#define MSG_TYPT_CLIENT 1
#define MSG_TYPE_SERVER 2

 

class MysQueue
{

public:


struct msgbuf
{
    long mtype;
    char mtext[default_size];

};
    MysQueue()
        : _msgfd(default_fd)
    {
    }
    ~MysQueue()
    {
    }
    void Create(int flag)
    {
        key_t key = ftok(PATH, PROJIN);
        if (key == -1)
        {
            perror("ftok");
            exit(1);
        }
        std::cout << "ftok success!" << std::endl;

        _msgfd = msgget(key, flag);
        if (_msgfd < 0)
        {
            perror("msgget");
            exit(1);
        }
        std::cout << "msgget success!" << std::endl;
    }

    // 发送消息
    void Send(int type, const std::string text)
    {
        msgbuf msg;
        msg.mtype = type;
        memset(msg.mtext, 0, sizeof(msg.mtext));
        memcpy(msg.mtext, text.c_str(), text.size());
        int n = msgsnd(_msgfd, &msg, sizeof(msg.mtext), 0);
        if (n < 0)
        {
            perror("msgsnd");
            exit(1);
        }
        std::cout << "send success!" << std::endl;
    }
    // 接收消息
    void Receive(int type, std::string &text)
    {
        msgbuf msg;
        int n = msgrcv(_msgfd, &msg, sizeof(msg.mtext), type, 0);
        //std::cout<<n<<std::endl;
        if (n < 0)
        {
            perror("msgrcv");
            exit(1);
        }
        std::cout << "receive success!" << std::endl;
        msg.mtext[n] = '\0';
        text = msg.mtext;
    }

    void Distory()
    {
        int n = msgctl(_msgfd, IPC_RMID, nullptr);
        if (n < 0)
        {
            perror("msgctl");
            exit(1);
        }
        std::cout << "msgctl success!" << std::endl;
    }

private:
    int _msgfd;
};

class MysQueue_serve : public MysQueue
{
public:
    MysQueue_serve()
    {
        MysQueue::Create(GET_MSGQUEUE);
        
    }

    ~MysQueue_serve()
    {
        

    }
};

class MysQueue_client : public MysQueue
{
public:
    MysQueue_client()
    {
        MysQueue::Create(GREAT_MSGQUEUE);
    }

    ~MysQueue_client()
    {
        MysQueue::Distory();
    }
};